using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using OpenComposite.EII;
using System.Diagnostics;

namespace OpenComposite.SOBADesigner
{
	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);
			AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

			// Add the event handler for handling UI thread exceptions to the event.
			Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
			Application.ApplicationExit += new EventHandler(Application_ApplicationExit);

			// Set the unhandled exception mode to force all Windows Forms errors to go through
			// our handler.
			Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

			// Add the event handler for handling non-UI thread exceptions to the event. 
			AppDomain.CurrentDomain.UnhandledException +=
				new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

			FormMain frmMain = null;
			bool logout = false;
			do {
				frmMain = new FormMain();
				Application.Run(frmMain);
				logout = frmMain.IsLogout;
				try {
					frmMain.Dispose();
					frmMain = null;
					GC.Collect();
				} catch { }
			} while ( logout );
		}

		private static void Application_ApplicationExit(object sender, EventArgs e)
		{
			Application.ApplicationExit -=
				new EventHandler(Application_ApplicationExit);
			Application.ThreadException -=
				new ThreadExceptionEventHandler(Application_ThreadException);
			AppDomain.CurrentDomain.UnhandledException -=
				new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
		}

		private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
		{
			// catch exception thrown if Team Foundation Explorer is not installed
			// (is handled by CurrentDomain_AssemblyLoad which is called after Application_ThreadException
			if ( e.Exception != null ) Debug.WriteLine(e.Exception.ToString());

			FileNotFoundException fileNotFoundEx = e.Exception as FileNotFoundException;

			if ( fileNotFoundEx != null ) {
				if ( fileNotFoundEx.FileName.Contains("Microsoft.TeamFoundation") ) {
					Global.Status.IsTfsInstalled = false;
					return;
				}
			}
			DialogResult result = DialogResult.Cancel;
			try {
				result = ShowThreadExceptionDialog(Application.ProductName + " Error", e.Exception);
			} catch {
				try {
					MessageBox.Show("Fatal " + Application.ProductName + " Error",
						"Fatal Windows Forms Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				} finally {
					Application.Exit();
				}
			}

			// Exits the program when the user clicks Abort.
			if ( result == DialogResult.Abort ) Application.Exit();
		}
		private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
		{
			try {
				Exception exception = (Exception)e.ExceptionObject;

				ApplicationError.Show(
					"Fatal Error",
					"An application error occurred." + Environment.NewLine +
					"Please contact the adminstrator with the following information:" + Environment.NewLine +
					exception.Message,
					"Stack Trace:" + Environment.NewLine + exception.StackTrace, false);

			} catch ( Exception ex ) {
				try {
					ApplicationError.Show(
						"Fatal Error",
						"An application error occurred." + Environment.NewLine +
						"Please contact the adminstrator with the following information:" + Environment.NewLine +
						ex.Message,
						"Stack Trace:" + Environment.NewLine + ex.StackTrace, false);
				} finally {
					Application.Exit();
				}
			}
		}
		private static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
		{
		}

		static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			if ( args.Name.Contains("Microsoft.TeamFoundation") && !args.Name.Contains("XmlSerializers") ) {
				Global.Status.IsTfsInstalled = false;
			}
			return null;
		}

		// Creates the error message and displays it.
		private static DialogResult ShowThreadExceptionDialog(string title, Exception e)
		{
			return ApplicationError.Show(
				title,
				"An application error occurred." + Environment.NewLine +
				"Please contact the adminstrator with the following information:" + Environment.NewLine +
				e.Message,
				"Stack Trace:" + Environment.NewLine + e.StackTrace, true);
		}
	}
}
